package cn.school.workmgr.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.school.common.utils.SysUserUtils;
import cn.school.workmgr.dao.ClockTimeDao;
import cn.school.workmgr.dao.FenceConfigDao;
import cn.school.workmgr.dao.FenceLocationDao;
import cn.school.workmgr.entity.RecruitBanner;
import cn.school.workmgr.entity.RecruitEnroll;
import cn.school.workmgr.service.FenceService;
import cn.school.workmgr.vo.ClockTimeVO;
import cn.school.workmgr.vo.FenceConfigVO;
import cn.school.workmgr.vo.FenceLocationVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class FenceServiceImpl extends ServiceImpl<FenceConfigDao,FenceConfigVO> implements FenceService {

    @Resource
    FenceLocationDao fenceLocationDao;
    @Resource
    ClockTimeDao clockTimeDao;


    @Override
    public IPage<FenceConfigVO> pageList(FenceConfigVO vo) {
        LambdaQueryWrapper<FenceConfigVO> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(FenceConfigVO::getTenantId, SysUserUtils.getSysUser().getTenantId());
        wrapper.orderByDesc(FenceConfigVO::getCreateBy);

        return page(new Page<>(vo.getPageNum(), vo.getPageSize()), wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrUpdateFenceConfig(FenceConfigVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        int num = 0;
        if(StringUtils.isEmpty(vo.getId())){
            vo.setCreateBy(username);
            vo.setCreateTime(new Date());
            vo.setFenced(vo.getLocationList().size()>0?"1":"0");

            this.baseMapper.insert(vo);
            //添加时间
            for (ClockTimeVO clockTimeVO : vo.getClockList()) {
                clockTimeVO.setFenceId(vo.getId());
                clockTimeDao.insert(clockTimeVO);
            }
            //添加围栏
            FenceLocationVO fenceLocationVO = null;

            for (Double[] dou : vo.getLocationList()) {
                fenceLocationVO = new FenceLocationVO();
                fenceLocationVO.setLongitude(dou[0]);
                fenceLocationVO.setLatitude(dou[1]);
                fenceLocationVO.setFenceId(vo.getId());
                fenceLocationDao.insert(fenceLocationVO);
            }
            num =1;
        }else{
            vo.setModifyBy(username);
            vo.setModifyTime(new Date());
            vo.setFenced(vo.getLocationList().size()>0?"1":"0");
            this.baseMapper.updateById(vo);

            //添加时间
            LambdaQueryWrapper<ClockTimeVO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ClockTimeVO::getFenceId,vo.getId());
            clockTimeDao.delete(lambdaQueryWrapper);
            for (ClockTimeVO clockTimeVO : vo.getClockList()) {
                clockTimeVO.setFenceId(vo.getId());
                clockTimeDao.insert(clockTimeVO);
            }
            LambdaQueryWrapper<FenceLocationVO> locationWrapper = new LambdaQueryWrapper<>();
            locationWrapper.eq(FenceLocationVO::getFenceId,vo.getId());
            fenceLocationDao.delete(locationWrapper);
            //添加围栏
            FenceLocationVO fenceLocationVO = null;
            for (Double[] dou : vo.getLocationList()) {
                fenceLocationVO = new FenceLocationVO();
                fenceLocationVO.setLongitude(dou[0]);
                fenceLocationVO.setLatitude(dou[1]);
                fenceLocationVO.setFenceId(vo.getId());
                fenceLocationDao.insert(fenceLocationVO);
            }
            num =1;
        }
        return num;
    }

    @Override
    public int deleteFenceConfig(Long id) {
        LambdaQueryWrapper<FenceLocationVO> locationWrapper = new LambdaQueryWrapper<>();
        locationWrapper.eq(FenceLocationVO::getFenceId,id);
        fenceLocationDao.delete(locationWrapper);

        LambdaQueryWrapper<ClockTimeVO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ClockTimeVO::getFenceId,id);
        clockTimeDao.delete(lambdaQueryWrapper);

        return this.baseMapper.deleteById(id);
    }

    @Override
    public FenceConfigVO fenceDetail(Long id) {
        FenceConfigVO vo = this.baseMapper.selectById(id);
        vo.setLocationList(new ArrayList<Double[]>());
        LambdaQueryWrapper<FenceLocationVO> locationWrapper = new LambdaQueryWrapper<>();
        locationWrapper.eq(FenceLocationVO::getFenceId,id);
        List<FenceLocationVO> fenceLocationVOS = fenceLocationDao.selectList(locationWrapper);
        Double[] location = null;
        for (FenceLocationVO fenceLocationVO : fenceLocationVOS) {
            location = new Double[2];
            location[0]=Double.valueOf(fenceLocationVO.getLongitude());
            location[1]=Double.valueOf(fenceLocationVO.getLatitude());
            vo.getLocationList().add(location);
        }

        LambdaQueryWrapper<ClockTimeVO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ClockTimeVO::getFenceId,id);
        vo.setClockList(clockTimeDao.selectList(lambdaQueryWrapper));


        return vo;
    }


    /**
     * 查询当前时间段可以打开的围栏信息
     * @return
     */
    @Override
    public List<FenceConfigVO> findCurrTimeUseFence() {
        String tenantId = SysUserUtils.getStudentUser().getTenantId();
        String time = DateUtil.format(new Date(),"HH:mm");
        //判断当前是否能够打卡
        List<FenceConfigVO> configList = this.baseMapper.currIsHaveUseFence(tenantId,time);

        return configList;
    }

    @Override
    public boolean fenceRange(double longitude, double latitude, Long fenceId) {
        LambdaQueryWrapper<FenceLocationVO> locationWrapper = new LambdaQueryWrapper<>();
        locationWrapper.eq(FenceLocationVO::getFenceId,fenceId);
        List<FenceLocationVO> fenceLocationVOS = fenceLocationDao.selectList(locationWrapper);

        return isPoint(fenceLocationVOS,longitude,latitude);
    }

    private static Path2D.Double create(List<FenceLocationVO> polygon) {

        //创建path2D对象
        Path2D.Double generalPath = new Path2D.Double();
        //获取第一个起点经纬度的坐标
        FenceLocationVO first = polygon.get(0);
        //通过移动到以double精度指定的指定坐标，把第一个起点添加到路径中
        generalPath.moveTo(first.getLatitude(), first.getLatitude());
        //把集合中的第一个点删除防止重复添加
        polygon.remove(0);
        //循环集合里剩下的所有经纬度坐标
        for (FenceLocationVO d : polygon) {
            //通过从当前坐标绘制直线到以double精度指定的新指定坐标，将路径添加到路径。
            //从第一个点开始，不断往后绘制经纬度点
            generalPath.lineTo(d.getLongitude(), d.getLatitude());
        }
        // 最后要多边形进行封闭，起点及终点
        generalPath.lineTo(first.getLongitude(), first.getLatitude());
        //将直线绘制回最后一个 moveTo的坐标来关闭当前子路径。
        generalPath.closePath();
        return generalPath;
    }
    /**
     * 判断点是否在区域内
     * @param polygon  区域经纬度json字符串
     * @param longitude 经度
     * @param latitude  纬度
     * @return 返回true跟false
     */

    public static boolean isPoint(List<FenceLocationVO> polygon, double longitude, double latitude) {
        Path2D path2D = create(polygon);
        //true如果指定的坐标在Shape边界内; 否则为false 。
        return path2D.contains(longitude, latitude);

    }
}
